The increasing use of the Internet and other distributed networks for a variety of purposes, including international commercial, scientific and cultural discourse, makes the ability to readily and reliably produce and support global software increasingly important. Global software, or applications, refers to software that is developed independently of specific languages or geographic regions and capable of being translated into any desired language or region of an end user at run-time.
The internationalization process implies that the software consists of a single set of binaries that operates under all languages, and that the language-sensitive areas in the source code, referred to as the “localizable areas”, such as end-user visible strings, data and numeric formats, are stored in external files. The C/C++ programming language, for instance, uses this internationalization model by storing the language-sensitive areas in external files called “message catalogs”. Message catalogs are based on the standard defined by the X/Open Portability Guide (XPG) and are thus very attractive for localization. These message catalogs are not source code but are text files, designed for localizability, that allow easy translation of texts into native languages, such as French, Italian, Russian, German or Japanese. The C/C++ programming language “loads” the appropriate language versions of these message catalogs based on the end-user's language at run-time. When a user starts up an internationalized application, the application first checks to see which locale is in use by the user. For instance, when a user runs an application on a German NT server, the user is using the German locale. The locale in use by the user, determined at run-time, will be used by the application for the display text and other user interface elements. If the user changes the locale in use, such as by restarting the desktop environment under another locale, the application will use that other locale to display the texts and other user interface elements.
This internationalization approach is not available for software written in the portable Java programming language by Sun Microsystems because the Java programming language does not store language-sensitive areas in the source code in message catalogs. The Java programming language provides a framework for developing global applications which allows for translation of end-user visible strings, referred to as “display strings” or “localizable strings,” that may be shown to an intended user and therefore need to be translated for different countries. A Java global application is comprised of a collection of related Java source code files, hereafter referred to as a “package”. Each of the Java source files contained in a package may contain display strings. To produce global software, these display strings need to be translated to different countries or languages of the intended users. This translation includes translation of messages, numbers, dates, and currency into a country's conventional formats. Non-display strings, such as comments and Universal Resource Locators (URLs), are used programmatically and are thus not translated.
As mentioned, the Java programming language does not store display strings in message catalogs but instead stores language-sensitive areas in a source code data structure referred to as a “ListResourceBundle”. Basically, a ListResourceBundle data structure provides a way to access display strings according to locale conventions. The ListResourceBundle data structure has a unique identifier to a display string, referred to as a “display string key”, that enables “display string value” mapping. A Java ListResourceBundle data structure can be stored in a separate external file and loaded at run-time.
FIGS. 1–2 provide an example of how Java programmers use existing Java methodology to internationalize a Java program and then how translators, also called localizers, subsequently localize the internationalized Java program. Referring to the flow chart 10 of FIG. 1, the first step, shown at Block 12, for internationalizing a Java program is to identify the localizable areas, such as localizable strings, within the Java source code. For purposes of this example only, assume that the Java code of interest is contained in a file named “myApplication.java”:                /* “Display adjustment” and “Volume adjustment” are the */ /* strings that needs to be made localizable. As it appears */ /* in this manner, they cannot be translated. */ myCheckbox1=new Checkbox(“Display adjustment”);        myCheckbox2=new Checkbox(“Volume adjustment”);It will be understood that only two strings have been shown in the example for ease of explanation and that one skilled in the art will recognize that Java source code will typically have dozens or even hundreds of strings. The next step, at Block 14, is to create a unique key for each of the identified localizable strings. Assume that the key for the localizable string “Display adjustment” will be “display_adj” and that the key for the localizable string “Volume adjustment” will be “volume_adj”. At Block 16, the next step is create a subclass of a ListResourceBundle and override its getContents( ) method that will contain the localizable string(s). The following is some sample Java code in a file called “myResources.java”:        
import java.util.*;public class myResources extends ListResourceBundle {public Object□□ getContents( ) { return contents };static final Object□□ contents = {{“display_adj”, “Display adjustment”},{“volume_adj”, “Volume adjustment”}};};Then, the locale in the source code must be determined so that the correct language version of ListResourceBundle can be loaded/accessed by the Java program at run-time, as shown in Block 18. Sample Java code that will accomplish this step is shown below and will be added prior to the Java code associated with Block 12 above:                /* Obtain the locale information for this application. */ /* If this Java program is running in French mode, */ /* “getDefault( )” will return French. */ Locale locale;        locale=Locale.getDefault( );        /* Use the locale information (from above) to obtain the */ /* locale-specific version of myResources. So, if the locale */ /* is set to French, the “getBundle( )” will return a French */ /* language version of the ListResourceBundle. */ public static ResourceBundle rb;        rb=ResourceBundle.getBundle(“myResources”, locale);Finally, at Block 20, the localizable string(s) are obtained from the ListResourceBundle. Sample Java code to accomplish this step in the “myApplication.java” file follows:        /* Obtain the locale information for this application. */ /* If this Java program is running in French mode, */ /* “getDefault( )” will return French. */ Locale locale;        locale=Locale.getDefault( );        /* Use the locale information (from above) to obtain the */ /* locale-specific version of myResources. So, if the locale */ /* is set to French, the “getBundle( )” will return a French */ /* language version of the ListResourceBundle. */ public static ResourceBundle rb;        rb=ResourceBundle.getBundle(“myResources”, locale);        /* Obtain the localizable strings by calling “getString( )”*/ /* and by passing the key for each of the localizable strings. */ /* So, if the above calls fetched a French ListResourceBundle, */ /* myResources.rb.getString(“display_adj”)*/ /* will return the French translation of the string */ /* “Display Adjustment”*/ myCheckbox1=new Checkbox(myResources.rb.getString(“display_adj”);        myCheckbox2=new Checkbox(myResources.rb.getString(“volume_adj”);        
The Java program has thus been internationalized according to the prior art method of FIG. 1. Now suppose that the internationalized Java program must be translated or localized to the desired locale. This methodology is illustrated by flow chart 30 of FIG. 2. The first step, at Block 32, is to obtain the ListResourceBundle for a given Java program that is to be localized. The ListResourceBundle will consist of Java code with “{key, value}” pairs. Sample Java code in the “myResources.java” file that will accomplish this step follows:
import java.util.*;public class myResources extends ListResourceBundle {public Object□□ getContents( ) { return contents };static final Object□□ contents = {{“display_adj”, “Display adjustment”},{“volume_adj”, “Volume adjustment”}};};The next step, at Block 34, is to translate only the “value” portion and not the “key” portion of the ListResourceBundle source code data structure, being sure not to modify anything else within the source file. The file may be renamed to indicate the translation language. For instance, the French version of the “myResources.java” file may be titled the “myResources_fr.java” file. Sample Java code in the “myResources_fr.java” file may be as follows:
import java.util.*;public class myResources extends ListResourceBundle {public Object□□ getContents( ) { return contents };static final Object□□ contents = {{“display_adj”, “Re'glage d'affichage”},{“volume_adj”, “Re'glage de volume”},};};
Unfortunately, using a ListResourceBundle data structure presents several disadvantages, as can be seen from the above example. First, ListResourceBundle data structures are source code and are therefore not easily translatable. Translators cannot use any of the “localization tools” applicable for message catalogs and the difficulty becomes distinguishing display strings which need to be translated from non-display strings which do not require translation. The Java code thus has to be combed manually, i.e. line-by-line, to identify the display strings that need to be translated. The display strings must then be changed manually to make it translatable. Needless to say, this process is very time-consuming and inefficient. While mechanisms such as PERL script may be used to assist in this endeavor, the results must still be checked manually.
Second, writing Java source code that loads and accesses a ListResourceBundle data structure is cumbersome. Additionally, identifying obsolete or new or modified strings that require new translations is difficult using a ListResourceBundle data structure. Modifying the Java source code without translating the accompanying ListResourceBundle data structure will cause the Java program to throw an exception, sometimes referred to as “throwing an exception,” similar to a core dump in a C program, for not being able to find a translated string. Finally, modifying an existing non-global application to use ListResourceBundle data structures is difficult because the process of separating the display strings from the Java source code generally cannot be done automatically. It is much easier to build a global program from the ground up rather than attempt to retrofit an existing non-global application because of this difficulty. It is therefore difficult to modify an existing Java-based non-global application to make it capable of using ListResourceBundle data structures.